#include "DockTab.h"
#include "DockingTabWell.h"
#include <QPainter>
#include <QApplication>
#include <QScreen>
#include <QTimer>
#include <QVBoxLayout>
#include <QLabel>
#include <QDateTime>
#include <QCursor>
#include <cmath>
#include <QDebug>
#include <cassert>
#include <QStyle>

// 静态常量定义
const QSize DockTab::PREVIEW_WINDOW_SIZE(640, 480);
const float DockTab::PREVIEW_OPACITY = 0.5f;
const int ANIMATION_FPS = 60;

DockTab::DockTab(const QString& title, QWidget* parent)
    : QPushButton(parent)
    , Title(title)
    , TabTypeValue(TabType::NormalTab)
    , IsActive(false)
    , ContentWidget(nullptr)
    , IsHovered(false)
    , IsCloseButtonHovered(false)
    , ShowCloseButton(true)
    , DragStateValue(DragState::None)
    , JustClicked(false)
    , DragAccepted(false)
    , CurrentIndex(-1)
    , LastSwapCheckX(0)
    , HasSwappedInCurrentDrag(false)
    , PreviewDropIndex(-1)
    , PreviewWindow(nullptr)
    , PreviewContent(nullptr)
    , AnimationTimer(new QTimer(this))
    , IsAnimating(false)
{
    setupTab();
}

DockTab::DockTab(const QIcon& icon, const QString& title, QWidget* parent)
    : QPushButton(parent)
    , Title(title)
    , Icon(icon)
    , TabTypeValue(TabType::NormalTab)
    , IsActive(false)
    , ContentWidget(nullptr)
    , IsHovered(false)
    , IsCloseButtonHovered(false)
    , ShowCloseButton(true)
    , DragStateValue(DragState::None)
    , JustClicked(false)
    , DragAccepted(false)
    , CurrentIndex(-1)
    , LastSwapCheckX(0)
    , HasSwappedInCurrentDrag(false)
    , PreviewDropIndex(-1)
    , PreviewWindow(nullptr)
    , PreviewContent(nullptr)
    , AnimationTimer(new QTimer(this))
    , IsAnimating(false)
{
    setupTab();
}

DockTab::~DockTab()
{
    destroyPreviewWindow();
    stopLinearAnimation();
}

void DockTab::setupTab()
{
    // 基础设置
    setCheckable(false);
    setFocusPolicy(Qt::NoFocus);
    setAttribute(Qt::WA_Hover, true);
    
    // 禁用默认文本显示，使用自定义绘制
    setText(""); // 清空文本，避免默认绘制干扰
    
    // 设置基础样式
    setMinimumSize(80, 30);
    setMaximumHeight(30);
    setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
    
    // 连接动画定时器
    connect(AnimationTimer, &QTimer::timeout, this, &DockTab::updateLinearAnimation);
    AnimationTimer->setInterval(1000 / ANIMATION_FPS); // 60fps
    
    // 连接基础信号
    connect(this, &QPushButton::clicked, this, &DockTab::tabActivated);
    
    updateTabAppearance();
}

// === 属性设置方法 ===

void DockTab::setTabTitle(const QString& title) {
    if (Title != title) {
        Title = title;
        // VSCode风格：tooltip显示完整标题
        setToolTip(Title);
        // 不调用setText，使用自定义绘制
        update(); // 触发重绘以显示新标题
    }
}

void DockTab::setTabIcon(const QIcon& icon) {
    if (Icon.cacheKey() != icon.cacheKey()) {
        Icon = icon;
        // 不调用setIcon，使用自定义绘制
        update(); // 触发重绘以显示新图标
    }
}

void DockTab::setTabType(TabType type) {
    if (TabTypeValue != type) {
        TabTypeValue = type;
        ShowCloseButton = isClosable();
        updateTabAppearance();
    }
}

void DockTab::setActiveTab(bool active) {
    if (IsActive != active) {
        IsActive = active;
        // 通过QSS属性驱动选中样式
        setProperty("active", IsActive);
        style()->unpolish(this);
        style()->polish(this);
        updateTabAppearance();
    }
}

void DockTab::setContentWidget(QWidget* widget) {
    // 断言：内容控件不应该是自己
    assert(widget != this && "Content widget cannot be the tab itself");
    
    ContentWidget = widget;
}

// === 位置管理 ===

void DockTab::setOriginalPosition(const QPoint& pos) {
    OriginalPosition = pos;
}

void DockTab::setFloatingPosition(const QPoint& pos) {
    if (FloatingPosition == pos) return; // 避免重复设置
    
    FloatingPosition = pos;
    
    // 确保标签能够脱离Layout约束，自由移动
    // 在拖拽开始时已经raise()，这里不重复调用
    move(pos);
}

void DockTab::setPreviewDropIndex(int index) {
    if (PreviewDropIndex != index) {
        PreviewDropIndex = index;
        emit horizontalDragPreview(parentTabWell()->getTabIndex(this), index);
    }
}

// === 鼠标事件处理 ===

void DockTab::mousePressEvent(QMouseEvent* event) {
    // 断言：事件不应该为空
    assert(event != nullptr && "Mouse event cannot be null");
    
    if (event->button() == Qt::LeftButton) {
        // 断言：拖拽状态应该是None
        assert(DragStateValue == DragState::None && "Drag state should be None when starting new drag");
        
        // 检查是否点击关闭按钮
        if (isClosable() && isPointInCloseButton(event->pos())) {
            emit tabCloseRequested();
            event->accept();
            return;
        }
        
        // 首先激活标签页（立即切换内容）
        emit tabActivated();
        
        // 记录点击信息，但不立即进入拖拽状态
        DragStartPos = event->globalPosition().toPoint();
        DragCurrentPos = DragStartPos;
        TabGrabOffset = event->pos();
        DragStateValue = DragState::None; // 暂时保持None状态
        DragAccepted = false;
        JustClicked = true; // 标记刚刚点击
    }
    
    QPushButton::mousePressEvent(event);
}

void DockTab::mouseMoveEvent(QMouseEvent* event) {
    // 更新悬停状态
    bool wasCloseHovered = IsCloseButtonHovered;
    IsCloseButtonHovered = isClosable() && isPointInCloseButton(event->pos());
    if (wasCloseHovered != IsCloseButtonHovered) {
        update();
    }
    
    // 处理拖拽逻辑
    if ((event->buttons() & Qt::LeftButton)) {
        QPoint currentGlobalPos = event->globalPosition().toPoint();
        
        // 如果刚点击且移动距离超过阈值，开始拖拽
        if (JustClicked) {
            int dragDistance = (currentGlobalPos - DragStartPos).manhattanLength();
            if (dragDistance > DRAG_THRESHOLD) {
                JustClicked = false;
                DragStateValue = DragState::Clicked;  // 现在才进入拖拽准备状态
                OriginalPosition = pos();  // 记录原始位置
                
                // 初始化卡牌交换状态
                CurrentIndex = -1;  // 将在processCardSwapLogic中获取
                LastSwapCheckX = currentGlobalPos.x();
                HasSwappedInCurrentDrag = false;
            }
        }
        
        // 如果已在拖拽状态，继续更新
        if (DragStateValue != DragState::None) {
            DragCurrentPos = currentGlobalPos;
            updateDragOperation(DragCurrentPos);
        }
    }
    
    QPushButton::mouseMoveEvent(event);
}

void DockTab::mouseReleaseEvent(QMouseEvent* event) {
    if (event->button() == Qt::MiddleButton && isClosable()) {
        emit tabCloseRequested();
        event->accept();
        return;
    }
    if (event->button() == Qt::LeftButton) {
        if (DragStateValue != DragState::None) {
            finishDragOperation(event->globalPosition().toPoint());
        }
        
        // 重置状态
        JustClicked = false;
        DragStateValue = DragState::None;
        
        // 重置卡牌交换状态
        CurrentIndex = -1;
        LastSwapCheckX = 0;
        HasSwappedInCurrentDrag = false;
        
        // 清除浮动位置，完全交还给布局管理
        FloatingPosition = QPoint();
        stopLinearAnimation();
        
        // 强制TabWell重新布局，确保标签回到正确位置
        DockingTabWell* tabWell = parentTabWell();
        if (tabWell) {
            // 强制重新布局所有标签，确保主标签回到正确位置
            tabWell->clearDraggedTab(); // 清除拖拽状态
        }
    }
    
    QPushButton::mouseReleaseEvent(event);
}

// === 拖拽逻辑核心 ===

void DockTab::startDragOperation(const QPoint& startPos) {
    if (!isDraggable()) return;
    
    OriginalPosition = pos();
    
    // 确保拖拽的标签在最顶层显示
    raise();
    
    // 重新计算抓取偏移，确保坐标系一致
    DockingTabWell* tabWell = parentTabWell();
    if (tabWell) {
        QPoint localStartPos = tabWell->mapFromGlobal(DragStartPos);
        QPoint tabPosInWell = mapToParent(QPoint(0, 0)); // 标签左上角在TabWell中的位置
        TabGrabOffset = localStartPos - tabPosInWell;
    }
    
    emit dragStarted(DragStateValue);
}

void DockTab::updateDragOperation(const QPoint& currentPos) {
    QPoint delta = currentPos - DragStartPos;
    
    // 判断拖拽类型
    if (DragStateValue == DragState::Clicked) {
        // 已经通过了DRAG_THRESHOLD检查，直接确定拖拽类型
        DragState newState = determineDragType(DragStartPos, currentPos);
        if (newState != DragState::None) {
            DragStateValue = newState;
            startDragOperation(currentPos);
        }
        return;
    }
    
    // 处理不同类型的拖拽
    switch (DragStateValue) {
        case DragState::HorizontalDrag:
            processHorizontalDrag(currentPos);
            break;
            
        case DragState::PullOutDrag:
            processPullOutDrag(currentPos);
            break;
            
        default:
            break;
    }
    
    emit dragPositionChanged(currentPos);
}

void DockTab::finishDragOperation(const QPoint& endPos) {
    DragState finishedState = DragStateValue;
    
    switch (DragStateValue) {
        case DragState::HorizontalDrag:
            if (hasValidDropPreview()) {
                commitHorizontalDrag();
                DragAccepted = true;
            } else {
                revertHorizontalDrag();
                DragAccepted = false;
            }
            break;
            
        case DragState::PullOutDrag:
            if (isMouseInTabWellArea(endPos)) {
                // 回到标签栏
                destroyPreviewWindow();
                emit returnToTabWell();
                revertHorizontalDrag();
                DragAccepted = false;
            } else {
                // 创建新窗口
                destroyPreviewWindow();
                createRealWindow(endPos);
                DragAccepted = true;
            }
            break;
            
        default:
            DragAccepted = false;
            break;
    }
    
    // 重置拖拽状态
    DragStateValue = DragState::None;
    PreviewDropIndex = -1;
    
    emit dragFinished(finishedState, DragAccepted);
}

// === 拖拽类型判断 ===

DockTab::DragState DockTab::determineDragType(const QPoint& startPos, const QPoint& currentPos) {
    QPoint delta = currentPos - startPos;
    
    if (shouldStartPullOutDrag(delta)) {
        return DragState::PullOutDrag;
    } else if (shouldStartHorizontalDrag(delta)) {
        return DragState::HorizontalDrag;
    }
    
    return DragState::None;
}

bool DockTab::shouldStartHorizontalDrag(const QPoint& delta) {
    // 只要不是拖出，就可以是水平拖拽（栏内重排）
    // 不再限制X轴最小距离，让用户可以更灵活地拖动
    Q_UNUSED(delta);
    return true;
}

bool DockTab::shouldStartPullOutDrag(const QPoint& delta) {
    if (!canPullOut()) return false;
    
    // 按照上下文规范：垂直离开标签栏阈值(30px或一行高度)触发拖出
    // 主要检查Y轴偏移，而不是X轴
    return abs(delta.y()) > PULLOUT_THRESHOLD;
}

// === 横排拖拽逻辑 ===

void DockTab::processHorizontalDrag(const QPoint& currentPos) {
    DockingTabWell* tabWell = parentTabWell();
    if (!tabWell) return;
    
    QPoint localPos = tabWell->mapFromGlobal(currentPos);
    
    // 在水平拖拽中，只允许X轴移动，Y轴保持在标签栏内
    QPoint newPos = localPos - TabGrabOffset;
    newPos.setY(0); // 强制Y轴在标签栏内
    
    setFloatingPosition(newPos);
    
    // 检查是否应该转换为拖出状态
    QPoint delta = currentPos - DragStartPos;
    if (canPullOut() && abs(delta.y()) > PULLOUT_THRESHOLD) {
        // 转换为拖出状态
        DragStateValue = DragState::PullOutDrag;
        processPullOutDrag(currentPos);
        return;
    }
    
    // 卡牌式位移调换逻辑
    processCardSwapLogic(localPos.x());
}

void DockTab::processCardSwapLogic(int currentX) {
    DockingTabWell* tabWell = parentTabWell();
    if (!tabWell) return;
    
    // 获取当前标签的索引
    if (CurrentIndex == -1) {
        CurrentIndex = tabWell->getTabIndex(this);
        if (CurrentIndex == -1) return;
        LastSwapCheckX = currentX; // 记录初始位置
    }
    
    // 检查是否需要与相邻标签交换
    int totalTabs = tabWell->tabCount();
    
    // 如果只有1个标签（主标签），允许拖拽但不进行交换
    if (totalTabs <= 1) {
        return; // 松开鼠标时会进入取消还原逻辑
    }
    
    // 防抖：只有移动距离足够大时才检查交换
    const int MIN_MOVEMENT = 10; // 最小移动距离
    if (abs(currentX - LastSwapCheckX) < MIN_MOVEMENT) {
        return;
    }
    
    // 计算标签宽度用于判断交换阈值
    QSize tabSize = tabWell->computeTabSize();
    int tabWidth = tabSize.width() - tabWell->overlapWidth();
    int swapThreshold = tabWidth / 3; // 超过标签宽度1/3时交换（更敏感）
    
    // 检查与左边标签的交换
    if (CurrentIndex > 0 && currentX < LastSwapCheckX) { // 向左移动
        DockTab* leftTab = tabWell->tabAt(CurrentIndex - 1);
        if (leftTab) {
            int leftTabRightEdge = CurrentIndex * tabWidth - tabWell->overlapWidth();
            if (currentX < leftTabRightEdge - swapThreshold) {
                // 与左边标签交换
                performCardSwap(CurrentIndex, CurrentIndex - 1);
                CurrentIndex--; // 更新当前索引
                HasSwappedInCurrentDrag = true;
                LastSwapCheckX = currentX; // 更新检查位置
                return;
            }
        }
    }
    
    // 检查与右边标签的交换
    if (CurrentIndex < totalTabs - 1 && currentX > LastSwapCheckX) { // 向右移动
        DockTab* rightTab = tabWell->tabAt(CurrentIndex + 1);
        if (rightTab) {
            int rightTabLeftEdge = (CurrentIndex + 1) * tabWidth - tabWell->overlapWidth();
            if (currentX > rightTabLeftEdge + swapThreshold) {
                // 与右边标签交换
                performCardSwap(CurrentIndex, CurrentIndex + 1);
                CurrentIndex++; // 更新当前索引
                HasSwappedInCurrentDrag = true;
                LastSwapCheckX = currentX; // 更新检查位置
                return;
            }
        }
    }
}

void DockTab::performCardSwap(int fromIndex, int toIndex) {
    DockingTabWell* tabWell = parentTabWell();
    if (!tabWell) return;
    
    // 执行标签交换（这里调用TabWell的方法来真正交换标签位置）
    emit horizontalDragCommit(fromIndex, toIndex);
    
    // 卡牌交换的视觉效果：轻微的弹跳反馈
    // 短暂向交换方向偏移，然后回到正常位置
    QPoint currentPos = pos();
    QPoint targetPos = tabWell->getTabPositionForIndex(toIndex);
    
    // 添加轻微的视觉反馈：朝交换方向偏移几像素后回弹
    int offsetDirection = (toIndex > fromIndex) ? 5 : -5;
    QPoint feedbackPos = targetPos + QPoint(offsetDirection, 0);
    
    // 先移动到反馈位置，然后回到目标位置
    move(feedbackPos);
    QTimer::singleShot(50, [this, targetPos]() {
        startLinearAnimation(pos(), targetPos, 100);
    });
}

int DockTab::calculateDropIndex(const QPoint& position) {
    DockingTabWell* tabWell = parentTabWell();
    if (!tabWell) return -1;
    
    // 这里需要调用tabWell的方法来计算放置索引
    // 根据鼠标位置和其他标签的位置来确定
    return tabWell->calculateDropIndexForPosition(position, this);
}

void DockTab::showHorizontalDragPreview(int targetIndex) {
    // 预览效果由TabWell处理
    setPreviewDropIndex(targetIndex);
}

void DockTab::commitHorizontalDrag() {
    DockingTabWell* tabWell = parentTabWell();
    if (!tabWell) return;
    
    // 卡牌交换模式：如果有交换发生，则确认当前位置；否则取消拖拽
    if (HasSwappedInCurrentDrag) {
        // 已经发生交换，标签应该停留在新位置
        // 不再自己动画，让DockingTabWell通过arrangeChildren()处理最终位置
        stopLinearAnimation();
    } else {
        // 没有交换发生，或者只有1个主标签时，取消拖拽
        revertHorizontalDrag();
    }
}

void DockTab::revertHorizontalDrag() {
    // 根据上下文规范：主标签可在栏内自由拖动但需要正确复位
    qDebug() << "DockTab::revertHorizontalDrag: Reverting tab" << Title 
             << "to original position, tabType:" << (int)TabTypeValue;
    
    // 清除浮动状态，回到布局管理
    stopLinearAnimation();
    
    // 重置拖拽相关状态
    HasSwappedInCurrentDrag = false;
    CurrentIndex = -1;
    
    // 强制清除浮动位置并重新设置几何体
    FloatingPosition = QPoint();
    
    // 通知TabWell重新布局
    DockingTabWell* tabWell = parentTabWell();
    if (tabWell) {
        // 确保标签回到其在标签列表中的正确位置
        int myIndex = tabWell->getTabIndex(this);
        if (myIndex >= 0) {
            // 立即设置到正确的几何体位置
            QPoint correctPosition = tabWell->getTabPositionForIndex(myIndex);
            QSize tabSize = tabWell->computeAdaptiveTabSize(myIndex);
            QRect correctGeometry(correctPosition, tabSize);
            setGeometry(correctGeometry);
            setOriginalPosition(correctGeometry.topLeft());
            qDebug() << "Reset tab" << Title << "to geometry:" << correctGeometry;
        }
    }
}

// === 拖出拖拽逻辑 ===

void DockTab::processPullOutDrag(const QPoint& currentPos) {
    if (!PreviewWindow) {
        createPreviewWindow(currentPos);
        emit pullOutDragStarted(TabGrabOffset);
    } else {
        updatePreviewWindow(currentPos);
    }
    
    // 检查是否回到标签栏内（Y轴距离小于阈值）
    DockingTabWell* tabWell = parentTabWell();
    if (tabWell) {
        QPoint localPos = tabWell->mapFromGlobal(currentPos);
        if (abs(localPos.y()) <= PULLOUT_THRESHOLD) {
            // 回到水平拖拽状态
            destroyPreviewWindow();
            DragStateValue = DragState::HorizontalDrag;
            processHorizontalDrag(currentPos);
            return;
        }
    }
    
    // 继续拖出状态 - 预览窗口跟随鼠标（Y轴自由移动）
    // updatePreviewWindow已经在上面调用，预览窗口会跟随鼠标
    
    emit pullOutPreviewMoved(currentPos);
}

void DockTab::createPreviewWindow(const QPoint& globalPos) {
    // 断言：预览窗口不应该已经存在
    assert(PreviewWindow == nullptr && "Preview window should not already exist");
    
    // 优雅处理：如果没有内容widget，创建占位预览
    if (PreviewWindow) return;
    
    if (!ContentWidget) {
        qDebug() << "DockTab::createPreviewWindow: No content widget for tab" << Title 
                 << "- creating placeholder preview";
        // 继续创建预览窗口，但使用占位内容
    }
    
    // 创建预览窗口
    PreviewWindow = new QWidget(nullptr);
    PreviewWindow->setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    PreviewWindow->setFixedSize(PREVIEW_WINDOW_SIZE);
    PreviewWindow->setWindowOpacity(PREVIEW_OPACITY); // 0.5透明度
    
    // 根据上下文规范：创建原标签按钮+对应Content组成的完整独立窗口快照
    QPixmap independentWindowSnapshot = captureIndependentWindowSnapshot();
    
    // 创建预览显示用的标签
    QLabel* previewLabel = new QLabel(PreviewWindow);
    previewLabel->setFixedSize(PREVIEW_WINDOW_SIZE);
    previewLabel->setScaledContents(true);
    previewLabel->setPixmap(independentWindowSnapshot);
    
    // 添加半透明白色遮罩效果，实现"半透发白"的需求
    previewLabel->setStyleSheet(QString(
        "QLabel { "
        "background-color: rgba(255, 255, 255, 150); " // 半透明白色遮罩
        "border: 2px solid #0078d4; "
        "border-radius: 8px; "
        "}"
    ));
    
    // 根据上下文规范：计算鼠标在快照中的精确位置
    calculateMousePositionInSnapshot(globalPos);
    
    updatePreviewWindow(globalPos);
    
    PreviewWindow->show();
}

void DockTab::updatePreviewWindow(const QPoint& globalPos) {
    if (!PreviewWindow) return;
    
    QPoint windowPos = globalPos + PreviewWindowOffset;
    
    // 确保窗口不超出屏幕边界
    QScreen* screen = QApplication::screenAt(globalPos);
    if (screen) {
        QRect screenGeometry = screen->availableGeometry();
        QSize windowSize = PreviewWindow->size();
        
        if (windowPos.x() + windowSize.width() > screenGeometry.right()) {
            windowPos.setX(screenGeometry.right() - windowSize.width());
        }
        if (windowPos.y() + windowSize.height() > screenGeometry.bottom()) {
            windowPos.setY(screenGeometry.bottom() - windowSize.height());
        }
        if (windowPos.x() < screenGeometry.left()) {
            windowPos.setX(screenGeometry.left());
        }
        if (windowPos.y() < screenGeometry.top()) {
            windowPos.setY(screenGeometry.top());
        }
    }
    
    PreviewWindow->move(windowPos);
}

void DockTab::destroyPreviewWindow() {
    if (PreviewWindow) {
        PreviewWindow->hide();
        PreviewWindow->deleteLater();
        PreviewWindow = nullptr;
    }
    
    if (PreviewContent) {
        PreviewContent->deleteLater();
        PreviewContent = nullptr;
    }
}

void DockTab::createRealWindow(const QPoint& globalPos) {
    if (!ContentWidget) return;
    
    // 1. 销毁预览窗口
    destroyPreviewWindow();
    
    // 2. 创建新的真实窗口
    QWidget* newWindow = new QWidget(nullptr);
    newWindow->setWindowFlags(Qt::Window);
    newWindow->setWindowTitle(Title);
    newWindow->resize(PREVIEW_WINDOW_SIZE);
    newWindow->move(globalPos);
    
    // 3. 从当前标签移除内容widget，添加到新窗口
    QWidget* contentToMove = ContentWidget;
    ContentWidget = nullptr; // 解除当前标签的内容关联
    
    // 创建新窗口的布局
    QVBoxLayout* windowLayout = new QVBoxLayout(newWindow);
    windowLayout->setContentsMargins(0, 0, 0, 0);
    windowLayout->addWidget(contentToMove);
    
    // 4. 显示新窗口
    newWindow->show();
    newWindow->raise();
    newWindow->activateWindow();
    
    // 5. 发送标签页"出队"的信号，让TabWell处理后续逻辑
    emit pullOutWindowRequested(globalPos, contentToMove);
    
    // 6. 从父TabWell中移除当前标签
    DockingTabWell* tabWell = parentTabWell();
    if (tabWell) {
        tabWell->removeTab(this);
    }
}

bool DockTab::isMouseInTabWellArea(const QPoint& globalPos) {
    DockingTabWell* tabWell = parentTabWell();
    if (!tabWell) return false;
    
    QRect tabWellRect = QRect(tabWell->mapToGlobal(QPoint(0, 0)), tabWell->size());
    return tabWellRect.contains(globalPos);
}

// === 线性动画系统 ===

void DockTab::startLinearAnimation(const QPoint& fromPos, const QPoint& toPos, int durationMs) {
    if (fromPos == toPos) return;
    
    stopLinearAnimation();
    
    AnimationStartPos = fromPos;
    AnimationEndPos = toPos;
    AnimationDuration = durationMs;
    AnimationStartTime = QDateTime::currentMSecsSinceEpoch();
    IsAnimating = true;
    
    AnimationTimer->start();
}

void DockTab::stopLinearAnimation() {
    if (IsAnimating) {
        AnimationTimer->stop();
        IsAnimating = false;
    }
}

void DockTab::updateLinearAnimation() {
    if (!IsAnimating) return;
    
    qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
    qint64 elapsed = currentTime - AnimationStartTime;
    
    if (elapsed >= AnimationDuration) {
        // 动画结束
        move(AnimationEndPos);
        onAnimationFinished();
        return;
    }
    
    // 计算当前进度 (0.0 to 1.0)
    float progress = static_cast<float>(elapsed) / AnimationDuration;
    
    // 使用easeOutQuad缓动函数
    progress = 1.0f - (1.0f - progress) * (1.0f - progress);
    
    QPoint currentPos = calculateLinearPosition(progress);
    move(currentPos);
}

QPoint DockTab::calculateLinearPosition(float progress) {
    int x = AnimationStartPos.x() + (AnimationEndPos.x() - AnimationStartPos.x()) * progress;
    int y = AnimationStartPos.y() + (AnimationEndPos.y() - AnimationStartPos.y()) * progress;
    return QPoint(x, y);
}

void DockTab::onAnimationFinished() {
    stopLinearAnimation();
    
    // 动画完成后的处理
    if (DragStateValue == DragState::None) {
        // 确保位置正确
        move(AnimationEndPos);
    }
}

// === 绘制相关 ===

void DockTab::paintEvent(QPaintEvent* event) {
    // 先让样式引擎绘制背景/边框（使QSS生效）
    QPushButton::paintEvent(event);
    
    // 再绘制自定义内容
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    paintTabContent(painter);
    
    if (ShowCloseButton && isClosable()) {
        paintCloseButton(painter);
    }
    
    if (DragStateValue == DragState::HorizontalDrag && hasValidDropPreview()) {
        paintDragPreview(painter);
    }
}

void DockTab::paintTabBackground(QPainter& painter) {
    Q_UNUSED(painter); // 由QSS提供背景与边框
}

void DockTab::paintTabContent(QPainter& painter) {
    QRect contentRect = rect();
    
    // VSCode风格：仅激活或悬停时显示关闭按钮，否则不占位
    bool showClose = isClosable() && (IsActive || IsHovered);
    if (showClose) {
        contentRect.setRight(contentRect.right() - CLOSE_BUTTON_SIZE - 8);
    }
    
    // 为图标留出空间
    if (!Icon.isNull()) {
        contentRect.setLeft(contentRect.left() + 20);
        
        // 绘制图标
        QRect iconRect(8, (height() - 16) / 2, 16, 16);
        painter.drawPixmap(iconRect, Icon.pixmap(16, 16));
    }
    
    // 计算文字区域，留出边距
    QRect textRect = contentRect.adjusted(8, 0, -8, 0);
    
    // 计算智能省略号文本
    QString displayText = calculateEllipsisText(Title, textRect.width(), painter.font());
    
    // 设置文字颜色
    QPen textPen;
    if (IsActive) {
        textPen.setColor(palette().color(QPalette::HighlightedText));
    } else {
        textPen.setColor(palette().color(QPalette::WindowText));
    }
    painter.setPen(textPen);
    
    // 绘制文字
    painter.drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, displayText);
}

QString DockTab::calculateEllipsisText(const QString& originalText, int availableWidth, const QFont& font) {
    QFontMetrics fm(font);
    
    // 如果文本能完全显示，直接返回
    if (fm.horizontalAdvance(originalText) <= availableWidth) {
        return originalText;
    }
    
    // 计算省略号的宽度
    QString ellipsis = "...";
    int ellipsisWidth = fm.horizontalAdvance(ellipsis);
    
    // 如果连省略号都显示不下，返回空字符串
    if (ellipsisWidth >= availableWidth) {
        return "";
    }
    
    // 二分查找最适合的字符数
    int left = 0;
    int right = originalText.length();
    QString result;
    
    while (left <= right) {
        int mid = (left + right) / 2;
        QString testText = originalText.left(mid) + ellipsis;
        
        if (fm.horizontalAdvance(testText) <= availableWidth) {
            result = testText;
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    
    return result.isEmpty() ? ellipsis : result;
}

// 移除对 QWidget::event 的重写，避免关键字命名冲突

void DockTab::paintCloseButton(QPainter& painter) {
    if (!isClosable()) return;
    
    QRect closeRect = closeButtonRect();
    
    // VSCode风格：仅激活或悬停时绘制关闭按钮
    if (!(IsActive || IsHovered)) return;
    
    if (IsCloseButtonHovered) {
        painter.fillRect(closeRect, palette().color(QPalette::Highlight));
    }
    
    // 绘制X标记
    painter.setPen(QPen(palette().color(QPalette::WindowText), 2));
    int margin = 4;
    painter.drawLine(closeRect.left() + margin, closeRect.top() + margin,
                    closeRect.right() - margin, closeRect.bottom() - margin);
    painter.drawLine(closeRect.right() - margin, closeRect.top() + margin,
                    closeRect.left() + margin, closeRect.bottom() - margin);
}

void DockTab::paintDragPreview(QPainter& painter) {
    // 绘制拖拽预览效果（如阴影、高亮等）
    painter.setOpacity(0.3);
    QRect previewRect = rect().adjusted(2, 2, 2, 2);
    painter.fillRect(previewRect, palette().color(QPalette::Shadow));
    painter.setOpacity(1.0);
}

// === 悬停事件 ===

void DockTab::enterEvent(QEnterEvent* event) {
    IsHovered = true;
    updateTabAppearance();
    update();
    QPushButton::enterEvent(event);
}

void DockTab::leaveEvent(QEvent* event) {
    IsHovered = false;
    IsCloseButtonHovered = false;
    updateTabAppearance();
    update();
    QPushButton::leaveEvent(event);
}

// === 工具函数 ===

QRect DockTab::closeButtonRect() const {
    if (!isClosable()) return QRect();
    
    int size = CLOSE_BUTTON_SIZE;
    return QRect(width() - size - 4, (height() - size) / 2, size, size);
}

bool DockTab::isPointInCloseButton(const QPoint& pos) const {
    return isClosable() && closeButtonRect().contains(pos);
}

void DockTab::updateTabAppearance() {
    // 同步active属性以便QSS选择器生效
    setProperty("active", IsActive);
    style()->unpolish(this);
    style()->polish(this);
    update();
}

DockingTabWell* DockTab::parentTabWell() const {
    // 向上查找父TabWell
    QWidget* p = parentWidget();
    while (p) {
        if (auto tabWell = qobject_cast<DockingTabWell*>(p)) {
            return tabWell;
        }
        p = p->parentWidget();
    }
    return nullptr;
}

QPixmap DockTab::captureContentSnapshot() {
    if (!ContentWidget) {
        // 根据上下文规范：优雅处理无内容的情况，创建有意义的占位图
        qDebug() << "DockTab::captureContentSnapshot: No content widget for tab" << Title 
                 << "- creating placeholder snapshot";
        
        QPixmap placeholder(PREVIEW_WINDOW_SIZE);
        placeholder.fill(QColor(240, 240, 240));
        
        QPainter painter(&placeholder);
        painter.setPen(QColor(100, 100, 100));
        painter.setFont(QFont("Arial", 16));
        painter.drawText(placeholder.rect(), Qt::AlignCenter, 
                        QString("Tab: %1\n(No Content)\n(Tab created but content not set)").arg(Title));
        
        return placeholder;
    }
    
    // 捕获实际内容widget的截图
    QPixmap snapshot = ContentWidget->grab();
    
    // 如果尺寸不匹配，缩放到预览窗口大小
    if (snapshot.size() != PREVIEW_WINDOW_SIZE) {
        snapshot = snapshot.scaled(PREVIEW_WINDOW_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation);
    }
    
    return snapshot;
}

QPixmap DockTab::captureIndependentWindowSnapshot() {
    // 根据上下文规范：创建原标签按钮+对应Content组成的完整独立窗口快照
    qDebug() << "DockTab::captureIndependentWindowSnapshot: Creating independent window snapshot for tab" << Title;
    
    // 创建独立窗口快照画布
    QPixmap snapshot(PREVIEW_WINDOW_SIZE);
    snapshot.fill(QColor(240, 240, 240)); // 浅灰色背景
    
    QPainter painter(&snapshot);
    painter.setRenderHint(QPainter::Antialiasing);
    
    // 1. 绘制窗口边框和标题栏区域
    painter.fillRect(0, 0, PREVIEW_WINDOW_SIZE.width(), 32, QColor(45, 45, 48)); // 深色标题栏
    
    // 2. 在顶部绘制标签按钮（原标签按钮的外观）
    QRect tabRect(8, 4, 120, 24); // 标签在独立窗口中的位置
    drawTabButtonInSnapshot(painter, tabRect);
    
    // 3. 绘制内容区域
    QRect contentRect(0, 32, PREVIEW_WINDOW_SIZE.width(), PREVIEW_WINDOW_SIZE.height() - 32);
    if (ContentWidget) {
        // 捕获内容widget的截图并绘制到内容区域
        QPixmap contentPixmap = ContentWidget->grab();
        if (!contentPixmap.isNull()) {
            painter.drawPixmap(contentRect, contentPixmap);
        } else {
            // 内容截图失败，绘制占位内容
            painter.fillRect(contentRect, QColor(64, 64, 64));
            painter.setPen(QColor(200, 200, 200));
            painter.setFont(QFont("Arial", 12));
            painter.drawText(contentRect, Qt::AlignCenter, QString("Content: %1").arg(Title));
        }
    } else {
        // 没有内容widget，绘制占位内容
        painter.fillRect(contentRect, QColor(64, 64, 64));
        painter.setPen(QColor(200, 200, 200));
        painter.setFont(QFont("Arial", 12));
        painter.drawText(contentRect, Qt::AlignCenter, QString("No Content\n%1").arg(Title));
    }
    
    // 记录标签按钮在快照中的位置，用于鼠标位置计算
    TabButtonRectInSnapshot = tabRect;
    
    return snapshot;
}

void DockTab::drawTabButtonInSnapshot(QPainter& painter, const QRect& tabRect) {
    // 绘制标签按钮在独立窗口快照中的外观
    painter.save();
    
    // 绘制标签背景（激活状态）
    QColor tabBgColor = IsActive ? QColor(0, 120, 212) : QColor(100, 100, 100);
    painter.fillRect(tabRect, tabBgColor);
    
    // 绘制标签边框
    painter.setPen(QColor(60, 60, 60));
    painter.drawRect(tabRect);
    
    // 绘制图标（如果有）
    int iconX = tabRect.x() + 4;
    if (!Icon.isNull()) {
        QRect iconRect(iconX, tabRect.y() + 4, 16, 16);
        painter.drawPixmap(iconRect, Icon.pixmap(16, 16));
        iconX += 20; // 为文本留出空间
    }
    
    // 绘制标签文本
    painter.setPen(QColor(255, 255, 255));
    painter.setFont(QFont("Arial", 9));
    QRect textRect(iconX, tabRect.y(), tabRect.width() - (iconX - tabRect.x()) - 4, tabRect.height());
    painter.drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, Title);
    
    painter.restore();
}

void DockTab::calculateMousePositionInSnapshot(const QPoint& globalPos) {
    // 根据上下文规范：鼠标在快照中的位置必须精确对应原始标签按钮的相对位置
    
    // 1. 计算鼠标在原始标签按钮中的相对位置
    QPoint localMousePos = mapFromGlobal(globalPos);
    QRect tabRect = rect(); // 当前标签按钮的矩形
    
    // 2. 计算鼠标在标签内的相对位置（0.0-1.0）
    float relativeX = 0.5f; // 默认中心
    float relativeY = 0.5f;
    
    if (tabRect.width() > 0 && tabRect.height() > 0) {
        relativeX = qBound(0.0f, (float)localMousePos.x() / tabRect.width(), 1.0f);
        relativeY = qBound(0.0f, (float)localMousePos.y() / tabRect.height(), 1.0f);
    }
    
    // 3. 将相对位置映射到快照中的标签按钮位置
    QPoint mouseInSnapshotTab = QPoint(
        TabButtonRectInSnapshot.x() + (int)(TabButtonRectInSnapshot.width() * relativeX),
        TabButtonRectInSnapshot.y() + (int)(TabButtonRectInSnapshot.height() * relativeY)
    );
    
    // 4. 计算预览窗口的偏移，使得鼠标位置对应快照中的标签按钮
    PreviewWindowOffset = QPoint(
        -mouseInSnapshotTab.x(),
        -mouseInSnapshotTab.y()
    );
    
    qDebug() << "DockTab::calculateMousePositionInSnapshot:"
             << "localMouse:" << localMousePos 
             << "relative:" << relativeX << relativeY
             << "mouseInSnapshot:" << mouseInSnapshotTab
             << "offset:" << PreviewWindowOffset;
}
